/*
 * Copyright (C) 2012-2013 Matthias Zeimer and the miniframes project group.
 * All rights reserved. 
 * 
 * Licensed under the Eclipse Public License, Version 1.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.opensource.org/licenses/EPL-1.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

/**
 * <p>
 * A minimal framework for easy creation of domain or technique specific values. 
 * Please refer the documentation of class 
 * {@link de.miniframes.minivalues.Value} for further details.
 * </p>
 * 
 * <h4><a name="examples">Examples</a></h4>
 * <p>
 * A minimal example with all base features:
 * <pre>
 * public final class InvoiceNumber extends DomainValue&lt;InvoiceNumber&gt;
 * {
 *     private static final long serialVersionUID = 6904363206246152537L;
 * 
 *     &#47;&#42;&#42; For serialisation support only! &#42;&#47;
 *     private InvoiceNumber()
 *     {
 *         super();
 *     }
 * 
 *     private InvoiceNumber(int numberAsInt)
 *     {
 *         super("%d", numberAsInt);
 *     }
 * 
 *     public static InvoiceNumber valueOf(int numberAsInt)
 *     {
 *         return new InvoiceNumber(numberAsInt);
 *     }
 * }
 * </pre>
 * 
 * The corresponding minimal unit test (here JUnit 4):
 * <pre>
 * public class InvoiceNumberTest
 * {
 *     &#64;Test
 *     public void commonValueRestritionsTest()
 *     {
 *         new ValueVerifier&lt;InvoiceNumber&gt;(InvoiceNumber.class)
 *                 .verifyAllRestrictions();
 *     }
 * }
 * </pre>
 * </p>
 * 
 * <h4><a name="dependencies">Dependencies</a></h4>
 * <p>
 * This framework is isolated from other miniFrames frameworks. Only dependency 
 * is JavaSE version 6.
 * </p>
 * 
 * <h4><a name="license">License</a></h4>
 * <p>
 * Licensed under the 
 * <a href="http://www.opensource.org/licenses/EPL-1.0">Eclipse Public License,
 * Version 1.0</a>
 * </p>
 * 
 * <h4><a name="futurevisions">Future visions, drafts, sketches</a></h4>
 * <p>
 * TODO Suggest: Move {@link de.miniframes.minivalues.UnmodifiableTimestamp} and
 * {@link de.miniframes.minivalues.UnmodifiableArray} to a sub-package 
 * {@code defaults} (but this would cause a cycle?!)
 * and move {@link de.miniframes.minivalues.ValueVerifier} and 
 * {@link de.miniframes.minivalues.InvalidValueClassDeclarationException} to a 
 * sub-package {@code testsupport}.
 * </p>
 * 
 * <p>
 * TODO Changes!?
 * <br />
 *  UnmodifiableTimestamp -> UnmodifiableDate
 *  --> In sub-package
 *  --> "sepzieller" Wert beerbt NICHT Value, daher gesondert als erlaubter 
 *       Typ aufführen, wie UnmodifiableArray
 *  <br />
 *  UnmodifiableArray auch in sub-package
 * <br />
 * ValueVerifier weg zugunsten von static Value.assertValueClassRules(
 *         Class&lt;V extends Value&lt;V&gt;&gt;, 
 *         boolean permitConstructorUseInsteadOfFactoryMethod); 
 * (spezielle und akzeptable Ausnahme, "... should be false. 
 * In very rare cases the immediate use of the constructor is preferred to a
 * factory method; in these rare cases pass true to this argument.)
 * OR
 * The verify method is called by the verifier on an instance (the method is 
 * hidden and called via reflection) -> The test support has an own package!
 * <br />
 * Add description for (Value format string):
 *         If custom format is needed: Remember: A format string has no need
 *         to contain any format directive, so valueOf can generate and pass
 *         a string that is used as a "format".
 * <br/>
 * Add Doc for:
 * // ... an abstract class could have a constructor like to pass 
 *         // concrete sub-classes args:
 *         // protected AbstractValue(
 *         //         int foo, 
 *         //         String bar, 
 *         //         Object... subClassesConstructorArgs) {
 *         //     super(foo, bar, subClassesConstructorArgs);
 *         //     
 *         //     // Cause this class is abstract we may check
 *         //     // constraints for foo and bar here.
 *         //
 *         //     this.foo = foo;
 *         //     this.bar = bar; 
 *         // }
 * </p>
 * 
 * 
 * 
 * 
 * 
 * <p>
 * Alternate version draft:
 * 
 * <pre>
 * public interface InvoiceNumber extends DomainValue {
 * 
 *     int runningNumber();
 *     String sign();
 *     
 *     static class Set extends ValueSet&lt;InvoiceNumber&gt; {
 *         public InvoiceNumber valueOf(int num, String sign)
 *         {
 *             set(num).to().runningNumber();
 *             set(sign).to().sign();
 *             setToString( String.format("%d - %s", num, sign) );
 *             return select();
 *         }
 *     }
 * }
 * </pre>
 * => Creates proxy that use all asigns and to String for equals/hashCode
 * => NO automatic comparable support
 * => Serialisation via {@link java.lang.reflect.InvocationHandler}s fields:
 *    String-array mit full method names and Serializable array (ordered the 
 *    same) with the assigned values property (-> fast access on proxy call).
 * => CONTRA: Ohne JDK 8 default methods no custom methods!
 * </p>
 * 
 * <p>
 * A JDK8 draft:
 * 
 * <pre>
 * public interface InvoiceNumber extends DomainValue {
 * 
 *     int runningNumber();
 *     String sign();
 *     
 *     default static valueOf(int num, String sign)
 *     {
 *         return Values.valueOf(InvoiceNumber.class)
 *             .to( InvoiceNumber::runningNumber() ).assign(num)
 *             .to( InvoiceNumber::sign() ).assign(sign)
 *             .toStringFormat("%d - %s", 
 *                     InvoiceNumber::runningNumber(), 
 *                     InvoiceNumber::sign() )
 *             .select();
 *     }
 *     
 *     // ODER
 *     
 *     default static valueOf(int num, String sign)
 *     {
 *         return Values.fromSetOf(InvoiceNumber.class)
 *             .where( InvoiceNumber::runningNumber() ).is(num)
 *             .where( InvoiceNumber::sign() ).is(sign)
 *             .withToStringFormat("%d - %s", 
 *                     InvoiceNumber::runningNumber(), 
 *                     InvoiceNumber::sign() )
 *             .withDifferenceCalculation( (thisValue, otherValue) -> {
 *                         return thisValue.runningNumber() -
 *                                 otherValue.runningNumber();
 *                     } )
 *             .select();
 *     }
 * }
 * </pre>
 * => custom methods as defaults (like nextNumber() or asXY() or so).
 * </p>
 * 
 * @version 0.1
 * @author Matthias Zeimer
 */
package de.miniframes.minivalues;

